package package1;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.ColorConvertOp;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import javax.imageio.ImageIO;

public class TestForPictureDealing {

	public static String IMAGE_TYPE_GIF = "gif";// 
	public static String IMAGE_TYPE_JPG = "jpg";// 
	public static String IMAGE_TYPE_JPEG = "jpeg";//
	public static String IMAGE_TYPE_BMP = "bmp";// 
	public static String IMAGE_TYPE_PNG = "png";// 
	public static String IMAGE_TYPE_PSD = "psd";// special for photo shop

	public final static void scale(String srcImageFile, String result, int scale, boolean flag) {
		try {
			BufferedImage src = ImageIO.read(new File(srcImageFile)); // read file
			int width = src.getWidth(); // 
			int height = src.getHeight(); //
			if (flag) {// enlarge 
				width = width * scale;
				height = height * scale;
			} else {// shrink
				width = width / scale;
				height = height / scale;
			}
			Image image = src.getScaledInstance(width, height, Image.SCALE_DEFAULT);
			BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			Graphics g = tag.getGraphics();
			g.drawImage(image, 0, 0, null); // draw picture
			g.dispose();
			ImageIO.write(tag, "JPEG", new File(result));// output to file
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * magnify or shrink according to proportion and ratio
	 * 
	 * @param srcImageFile   input picture address
	 * @param result  output file address 
	 * @param height  aim height
	 * @param width  aim width
	 * @param bb  if needs a white filler, true for yes, false for no
	 *      the filler would fill white for the null content
	 *            
	 */
	public final static void scale2(String srcImageFile, String result, int height, int width, boolean bb) {
		try {
			double ratio = 0.0; // enlarge or shrink proportion and ratio
			File f = new File(srcImageFile);
			BufferedImage bi = ImageIO.read(f);
			Image itemp = bi.getScaledInstance(width, height, bi.SCALE_SMOOTH);
			// calculate proportion and ratio
			if ((bi.getHeight() > height) || (bi.getWidth() > width)) {
				if (bi.getHeight() > bi.getWidth()) {
					ratio = (new Integer(height)).doubleValue() / bi.getHeight();
				} else {
					ratio = (new Integer(width)).doubleValue() / bi.getWidth();
				}
				AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);
				itemp = op.filter(bi, null);
			}
			if (bb) {// make a white filler for the null content
				BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
				Graphics2D g = image.createGraphics();
				g.setColor(Color.white);
				g.fillRect(0, 0, width, height);
				if (width == itemp.getWidth(null))
					g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null),
							itemp.getHeight(null), Color.white, null);
				else
					g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null),
							itemp.getHeight(null), Color.white, null);
				g.dispose();
				itemp = image;
			}
			ImageIO.write((BufferedImage) itemp, "JPEG", new File(result));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 *  cut picture according to the height and width of the start point 
	 * 
	 * @param srcImageFile  source picture address
	 * @param result   output file address
	 * @param x    X for the start point to cut
	 * @param y    Y for the start point to cut
	 * @param width  the width for the cut slice
	 * @param height  the height for the cut slice
	 */
	public final static void cut(String srcImageFile, String result, int x, int y, int width, int height) {
		try {
			//read the source picture
			BufferedImage bi = ImageIO.read(new File(srcImageFile));
			int srcWidth = bi.getHeight(); 
			int srcHeight = bi.getWidth();  
			if (srcWidth > 0 && srcHeight > 0) {
				// the width, height for source picture
				Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);
				// CropImageFilter(int x,int y,int width,int height)
				ImageFilter cropFilter = new CropImageFilter(x, y, width, height);
				Image img = Toolkit.getDefaultToolkit()
						.createImage(new FilteredImageSource(image.getSource(), cropFilter));
				BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
				Graphics g = tag.getGraphics();
				g.drawImage(img, 0, 0, width, height, null); // draw the cropped picture
				g.dispose();//output to file
				ImageIO.write(tag, "JPEG", new File(result));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * crop picture according to the designated rows and colums 
	 * @param srcImageFile  source picture address
	 * @param descDir  output picture address
	 * @param rows    rows for the picture to be cropped, must be within [1,20] 
	 * @param cols	  columns for the picture to be cropped, must be within [1,20]
	 */
	public final static void cut2(String srcImageFile, String descDir, int rows, int cols) {
		try {
			if (rows <= 0 || rows > 20)
				rows = 2; // rows for the picture to be cropped
			if (cols <= 0 || cols > 20)
				cols = 2; // columns for the picture to be cropped
			// read source picture
			BufferedImage bi = ImageIO.read(new File(srcImageFile));
			int srcWidth = bi.getHeight(); 
			int srcHeight = bi.getWidth(); 
			if (srcWidth > 0 && srcHeight > 0) {
				Image img;
				ImageFilter cropFilter;
				Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);
				int destWidth = srcWidth; // define the width for picture to be cropped
				int destHeight = srcHeight; // define the height for picture to be cropped
				// calculate the height and width for the picture to be cropped
				if (srcWidth % cols == 0) {
					destWidth = srcWidth / cols;
				} else {
					destWidth = (int) Math.floor(srcWidth / cols) + 1;
				}
				if (srcHeight % rows == 0) {
					destHeight = srcHeight / rows;
				} else {
					destHeight = (int) Math.floor(srcWidth / rows) + 1;
				}
				// circle to create a cropped picture
				// think: if we could user multiple threads to speed up
				for (int i = 0; i < rows; i++) {
					for (int j = 0; j < cols; j++) {
						// 4 parameters to mark the start point and the height and width
						// CropImageFilter(int x,int y,int width,int height)
						cropFilter = new CropImageFilter(j * destWidth, i * destHeight, destWidth, destHeight);
						img = Toolkit.getDefaultToolkit()
								.createImage(new FilteredImageSource(image.getSource(), cropFilter));
						BufferedImage tag = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB);
						Graphics g = tag.getGraphics();
						g.drawImage(img, 0, 0, null); //draw picture according to parameters
						g.dispose(); // output to picture file
						ImageIO.write(tag, "JPEG", new File(descDir + "_r" + i + "_c" + j + ".jpg"));
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * crop picture with designated height and width
	 * 
	 * @param srcImageFile  source picture address
	 * @param descDir   output picture address
	 * @param destWidth    width setting for the cropped picture(00 by default)
	 * @param destHeight   height setting for the cropped picture(50 by default)
	 */
	public final static void cut3(String srcImageFile, String descDir, int destWidth, int destHeight) {
		try {
			if (destWidth <= 0)
				destWidth = 200; // width for the cropped picture
			if (destHeight <= 0)
				destHeight = 150; // height for the cropped picture
			// read source picture
			BufferedImage bi = ImageIO.read(new File(srcImageFile));
			int srcWidth = bi.getHeight(); 
			int srcHeight = bi.getWidth(); 
			if (srcWidth > destWidth && srcHeight > destHeight) {
				Image img;
				ImageFilter cropFilter;
				Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);
				int cols = 0; // how many columns for the cropped picture
				int rows = 0; // how many rows for the cropped picture
				// calculate the number for columns and rows
				if (srcWidth % destWidth == 0) {
					cols = srcWidth / destWidth;
				} else {
					cols = (int) Math.floor(srcWidth / destWidth) + 1;
				}
				if (srcHeight % destHeight == 0) {
					rows = srcHeight / destHeight;
				} else {
					rows = (int) Math.floor(srcHeight / destHeight) + 1;
				}
				// loop to create rows and columns
				for (int i = 0; i < rows; i++) {
					for (int j = 0; j < cols; j++) {
						// 4 parameters to mark the start point and the heigh and width
						// CropImageFilter(int x,int y,int width,int height)
						cropFilter = new CropImageFilter(j * destWidth, i * destHeight, destWidth, destHeight);
						img = Toolkit.getDefaultToolkit()
								.createImage(new FilteredImageSource(image.getSource(), cropFilter));
						BufferedImage tag = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB);
						Graphics g = tag.getGraphics();
						g.drawImage(img, 0, 0, null); 
						g.dispose();//output 
						ImageIO.write(tag, "JPEG", new File(descDir + "_r" + i + "_c" + j + ".jpg"));
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * picture type convert: GIF->JPG; GIF->PNG; PNG->JPG; PNG->GIF(X); BMP->PNG
	 * 
	 * @param srcImageFile  source of image file
	 * @param formatName	full name for the image file with suffix extension(JGP, JPEG, GIF)  
	 * @param destImageFile   source of output address
	 */
	public final static void convert(String srcImageFile, String formatName, String destImageFile) {
		try {
			File f = new File(srcImageFile);
			f.canRead();
			f.canWrite();
			BufferedImage src = ImageIO.read(f);
			ImageIO.write(src, formatName, new File(destImageFile));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * convert from color to black-white
	 * @param srcImageFile  source of image file
	 * @param destImageFile  output source
	 */
	public final static void gray(String srcImageFile, String destImageFile) {
		try {
			BufferedImage src = ImageIO.read(new File(srcImageFile));
			ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
			ColorConvertOp op = new ColorConvertOp(cs, null);
			src = op.filter(src, null);
			ImageIO.write(src, "JPEG", new File(destImageFile));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * add water mark(character) for the image
	 * @param pressText  text of the water mark(character) to be pressed
	 * @param srcImageFile   source of the image file
	 * @param destImageFile    source of output
	 * @param fontName    font name for the water mark(character) 
	 * @param fontStyle		font type
	 * @param color   font color
	 * @param fontSize   font size
	 * @param x   corrected value for the water mark(character)
	 * @param y   corrected value for the water mark(character)
	 * @param alpha    transparency for the water mark(character) [0.0, 1.0] float type
	 */
	public final static void pressText(String pressText, String srcImageFile, String destImageFile, String fontName,
			int fontStyle, Color color, int fontSize, int x, int y, float alpha) {
		try {
			File img = new File(srcImageFile);
			Image src = ImageIO.read(img);
			int width = src.getWidth(null);
			int height = src.getHeight(null);
			BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			Graphics2D g = image.createGraphics();
			g.drawImage(src, 0, 0, width, height, null);
			g.setColor(color);
			g.setFont(new Font(fontName, fontStyle, fontSize));
			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
			// create water mark at the designated location
			g.drawString(pressText, (width - (getLength(pressText) * fontSize)) / 2 + x, (height - fontSize) / 2 + y);
			g.dispose();
			ImageIO.write((BufferedImage) image, "JPEG", new File(destImageFile));// output
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * add water mark(character) for the image
	 * @param pressImg   source of image to be pressed
	 * @param srcImageFile   source of the mother image
	 * @param destImageFile	  source of output
	 * @param x   corrected value for the water mark(image)
	 * @param y   corrected value for the water mark(image)
	 * @param alpha   transparency for the water mark(image) [0.0, 1.0] float type
	 */
	public final static void pressImage(String pressImg, String srcImageFile, String destImageFile, int x, int y,
			float alpha) {
		try {
			File img = new File(srcImageFile);
			Image src = ImageIO.read(img);
			int wideth = src.getWidth(null);
			int height = src.getHeight(null);
			BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);
			Graphics2D g = image.createGraphics();
			g.drawImage(src, 0, 0, wideth, height, null);
			// water mark image
			Image src_biao = ImageIO.read(new File(pressImg));
			int wideth_biao = src_biao.getWidth(null);
			int height_biao = src_biao.getHeight(null);
			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
			g.drawImage(src_biao, (wideth - wideth_biao) / 2+x, (height - height_biao) / 2+y, wideth_biao, height_biao,
					null);
			g.dispose();
			ImageIO.write((BufferedImage) image, "JPEG", new File(destImageFile));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * calculate length of the text(1 Chinese regarded as 2 characters)
	 * @param text
	 * @return
	 */
	public final static int getLength(String text) {
		int length = 0;
		for (int i = 0; i < text.length(); i++) {
			if (new String(text.charAt(i) + "").getBytes().length > 1) {
				length += 2;
			} else {
				length += 1;
			}
		}
		return length / 2;
	}

	@SuppressWarnings("unused")
	public static void main(String[] args) throws IOException {
		String picAddr1 = "C:\\Users\\alvin.wang\\Desktop\\test\\111.jpg";
		String picAddr2 = "C:\\Users\\alvin.wang\\Desktop\\test\\222.jpg";
		String picShuiYinAddr = "C:\\Users\\alvin.wang\\Desktop\\test\\shuiyin.jpg";
		
//      enlarge or shrink according to proportion and ratio (true enlarge; false shrink)
        scale(picAddr1, picAddr2, 2, true);
        
//      zoom according to height and width
        scale2(picAddr1, picAddr2, 40, 400, true);
        
//      image crop according to start point location and given height and width
        cut(picAddr1, picAddr2, 0, 0, 1400, 1400 );
        
//      image crop according to given rows and columns for crop size
        cut2(picAddr1, picAddr2, 2, 1 );
        
//      image crop according to given width and height for crop size
        cut3(picAddr1, picAddr2, 50, 100 );
        
//      image type(suffix and extension) convert
        convert(picAddr1, "GIF", picAddr2.substring(0,picAddr2.length()-4)+".gif");
        
//      image convert from color to black-white
        gray(picAddr1, picAddr2);
        
//      press text and character into image as water mark eg1         // font type: song ti 
        pressText("press text eg1",picAddr1,picAddr2,"宋体",Font.BOLD,Color.white,20, 0, 0, 1.0f);
        
//      press text and character into image as water mark eg2        // font type: hei ti
        pressText("press text eg2", picAddr1,picAddr2, "黑体", 36, Color.blue, 20, 0, 0, 0.5f);
        
//      press image into image as water mark
        pressImage(picShuiYinAddr, picAddr1,picAddr2, -20, -20, 0.382f);
	}
}
